package com.fezs.common.context;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.fezs.common.model.LoginUser;
import org.slf4j.MDC;

import java.util.HashMap;
import java.util.Map;

/**
 * @author zhukai
 * @since 2022/8/18
 */
public class BaseContextHandler {

    public static final String USER_ID = "userId";
    public static final String TRACEID = "traceId";
    public static final String LOGIN_USER = "loginUser";

    public static final TransmittableThreadLocal<Map<String, Object>> threadLocal = new TransmittableThreadLocal<>();

    public static Long getUserId() {
        return Convert.toLong(get(USER_ID), 0L);
    }

    public static void setUserId(Long userId) {
        set(USER_ID, userId);
    }

    public static LoginUser getLoginUser() {
        return (LoginUser) get(LOGIN_USER);
    }

    public static void setLoginUser(LoginUser loginUser) {
        set(LOGIN_USER, loginUser);
    }

    public static String getTraceId() {
        String traceId = (String) get(TRACEID);
        return StrUtil.emptyToDefault(traceId, MDC.get(TRACEID));
    }

    public static void setTraceId(String traceId) {
        set(TRACEID, traceId);
    }

    private static Map<String, Object> init() {
        Map<String, Object> map = getAll();
        if (map == null) {
            map = new HashMap<>();
            threadLocal.set(map);
        }
        return map;
    }

    public static void set(String key, Object value) {
        Map<String, Object> map = init();
        map.put(key, value);
    }

    public static void putAll(Map<String, Object> anotherMap) {
        Map<String, Object> map = init();
        map.putAll(anotherMap);
    }

    public static Object get(String key) {
        Map<String, Object> map = threadLocal.get();
        if (map != null) {
            return map.get(key);
        }
        return null;
    }

    public static Map<String, Object> getAll() {
        return threadLocal.get();
    }

    public static void remove() {
        threadLocal.remove();
    }

    public static void del(String key) {
        Map<String, Object> map = getAll();
        if (map != null) {
            map.remove(key);
        }
    }
}
